# This code is hosted on http://code.google.com/p/lenthorp/
# Freely available for use in applications, but should NOT be modified
# Email all comments to lenthorpresearch@gmail.com

import scipy as sp
from scipy import optimize
from scipy.stats import norm

#import HHWCalibration

def BlackScholesPrice(F0, K, rd, tau, ivol, putCall=1):
    # putCall is 1 for a call, -1 for a put
    d1 = (sp.log(F0 / K) + (0.5 * ivol ** 2 * tau))/ (ivol * sp.sqrt(tau))
    d2 = d1 - ivol * sp.sqrt(tau)
    
    f = putCall * (sp.exp(-rd * tau) * (F0 * norm.cdf(putCall*d1) - K * norm.cdf(putCall*d2)))
    return max(f, 1e-08)
              

def CalcBlackScholesImpliedVol(price, F0, K, rd, tau, putCall=1):   
    minimizer = lambda IV, v0, v1, v2, v3, v4 : abs(v0 - BlackScholesPrice(v1, v2, v3, v4, IV, putCall))
    vol_initial = 0.40
    return optimize.fmin(minimizer, vol_initial, args=(price, F0, K, rd, tau), maxiter=1000, maxfun=1000, xtol=1e-05)
    

##def BS_vol_SV_HHW(F0, K, rd, tau, H_param):        
##    price = max(SV_HHW_Call_Calib_Partial(F0, K, rd, tau, H_param), 1e-08)
##    return BlackScholesImpliedVol(price, F0, K, rd, tau) * 100.0